package com.water_work_form.exception;

import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.water_work_form.result.Result;
import com.water_work_form.result.ResultCodeEnum;
import com.water_work_form.result.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.validation.UnexpectedTypeException;
import java.sql.SQLIntegrityConstraintViolationException;

@Slf4j
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

//    /**
//     * 通用异常处理
//     * @param e
//     * @return
//     */
//    @ExceptionHandler(value = Exception.class)
//    public Result exceptionHandler(Exception e){
//        log.error(e.getLocalizedMessage());
//        return ResultUtil.error(ResultCodeEnum.SYS_ERROR);
//    }

    /**
     * 格式错误
     * @param e
     * @return
     */
    @ExceptionHandler(value = {UnexpectedTypeException.class})
    public Result handleUnexpectedTypeException(Exception e){
        log.error(e.getLocalizedMessage());
        return ResultUtil.error(ResultCodeEnum.FORMAT_ERROR);
    }

    /**
     * 签名不合法
     * @param e
     * @return
     */
    @ExceptionHandler(value = {SignatureVerificationException.class})
    public Result handleSignatureVerificationException(Exception e){
        log.error(e.getLocalizedMessage());
        return ResultUtil.error(ResultCodeEnum.SIGNATURE_INVALID);
    }

    /**
     * token过期
     * @param e
     * @return
     */
    @ExceptionHandler(value = {TokenExpiredException.class})
    public Result handleTokenExpiredException(Exception e){
        log.error(e.getLocalizedMessage());
        return ResultUtil.error(ResultCodeEnum.TOKEN_EXPIRED);
    }

    /**
     * 认证失败
     * @param e
     * @return
     */
    @ExceptionHandler(value = {JWTDecodeException.class})
    public Result handleJWTDecodeException(Exception e){
        log.error(e.getLocalizedMessage());
        return ResultUtil.error(ResultCodeEnum.AUTHORITY_FAILED);
    }

    /**
     * 重复插入
     * @param e
     * @return
     */
    @ExceptionHandler(value = {SQLIntegrityConstraintViolationException.class})
    public Result handleSQLIntegrityConstraintViolationException(Exception e){
        log.error(e.getLocalizedMessage());
        return ResultUtil.error(ResultCodeEnum.REPEAT_INSERT);
    }

    /**
     * 错误请求
     * @param e
     * @return
     */
    @ExceptionHandler(value = {MethodArgumentNotValidException.class, HttpMessageNotReadableException.class, MissingServletRequestParameterException.class})
    public Result handleRequestFormatError(Exception e){
        log.error(e.getLocalizedMessage());
        return ResultUtil.error(ResultCodeEnum.BAD_REQUEST, e.getMessage());
    }

    /**
     * 资源不存在
     * @param e
     * @return
     */
    @ExceptionHandler(value = NoHandlerFoundException.class)
    public Result handleNoHandlerFoundException(NoHandlerFoundException e){
        log.error(e.getLocalizedMessage());
        return ResultUtil.error(ResultCodeEnum.NOT_FOUND);
    }

    /**
     * 请求方法被禁止
     * @param e
     * @return
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public Result handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e){
        log.error(e.getLocalizedMessage());
        return ResultUtil.error(ResultCodeEnum.REQ_MODE_NOT_SUPPORTED);
    }

    /**
     * 参数错误
     * @param e
     * @return
     */
    @ExceptionHandler(value = IllegalArgumentException.class)
    public Result handleIllegalArgumentException(IllegalArgumentException e){
        log.error(e.getLocalizedMessage());
        return ResultUtil.error(ResultCodeEnum.PARAM_ERROR);
    }


}
